package com.atguigu.mq.listener;

import com.rabbitmq.client.Channel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

import java.io.IOException;

@Component
@Slf4j
public class MyMessageListener {

    //@RabbitListener(queues = "atguigu.queue.direct02")

    /**
     * durable = "true"     是否为持久化队列，服务器重启，队列是否还存在。推荐true
     * exclusive = "false"  是否为排他队列，排他队列只限于当前连接使用，连接关闭，队列会被删除。推荐false
     * autoDelete = "false"  是否为自动删除队列。长时间不使用，服务器会删除队列。推荐false
     * declare = "true"     是否为自动声明的队列。不存在就创建，在就使用。
     *
     */
    @RabbitListener(
            bindings = {
                    @QueueBinding(
                            value= @Queue(name="atguigu.queue.direct02",durable = "true",exclusive = "false",autoDelete = "false",declare = "true"),
                            exchange = @Exchange(name="atguigu.exchange.direct"),
                            key = {
                                "b","c","a"
                            }
                    )
            }
    )
    public void processMessage(String dataString, Message message, Channel channel) throws  Exception {
        long deliveryTag = message.getMessageProperties().getDeliveryTag(); //消息唯一标识。id
        try {
            log.info("dataString="+dataString);

            //假设业务逻辑失败
            int i = 1/0;

            channel.basicAck(deliveryTag,false); //手动确认    multiple=true表示一次确认多条消息，效率高；重要消息推荐一条一条确认.multiple=false
        } catch (Exception e) {
            //e.printStackTrace();
            Boolean redelivered = message.getMessageProperties().getRedelivered(); //是否为重复投递的消息
            if(redelivered){  // true表示消息为重复投递
                channel.basicReject(deliveryTag,false); //requeue=false表示要么丢弃，要么去死信队列。
            }else{ //首次投递
                channel.basicNack(deliveryTag,false,true); //requeue=true 表示回到原队列，可以重新再进行投递。
            }

        }
    }

}
